Amazon Redshiftで列圧縮エンコーディングをALTER TABLEコマンドで変更してみた
先日、Amazon Redshiftで列圧縮エンコーディングの変更がALTER TABLEコマンドで実行できるようになったので試してみました!
嬉しいポイント
既存のテーブルに対して列圧縮エンコーディングを変更する場合は、下記の手間がありました。
- 新規で列圧縮エンコーディングを定義済みのテーブルを作成、既存テーブルのデータ移行が必要
- 実際の本番環境で稼働しているRedshiftクラスタなどの場合は、念のために事前にスナップショットを取得する
- 列圧縮エンコーディングを変更したい対象カラムが1つの場合でも、テーブルを再作成しないといけない
今回のアップデートにより、上記を考慮する必要なくALTER TABLE [対象テーブル名] ALTER COLUMN [対象カラム名] ENCODE [変更したい列圧縮エンコーディング名]
コマンドで列圧縮エンコーディングが変更できるようになりました。
動作環境
- クライアント:psql 12.3
- Redshiftクラスター(ノード:dc2.large、ノード数:1):1.0.20091 ※1.0.19506以降のバージョンで確認可能
サンプルデータ
下記のとおり、テーブル作成・ロードして検証していきます、
dev=# CREATE SCHEMA sample; CREATE SCHEMA dev=# dev=# CREATE TABLE sample.lineorder dev-# ( dev(# lo_orderkey INTEGER NOT NULL ENCODE ZSTD, dev(# lo_linenumber INTEGER NOT NULL ENCODE AZ64, dev(# lo_custkey INTEGER NOT NULL ENCODE AZ64, dev(# lo_partkey INTEGER NOT NULL ENCODE AZ64, dev(# lo_suppkey INTEGER NOT NULL ENCODE ZSTD, dev(# lo_orderdate INTEGER NOT NULL ENCODE AZ64, dev(# lo_orderpriority VARCHAR(15) NOT NULL ENCODE LZO, dev(# lo_shippriority VARCHAR(1) NOT NULL ENCODE ZSTD, dev(# lo_quantity INTEGER NOT NULL ENCODE AZ64, dev(# lo_extendedprice INTEGER NOT NULL ENCODE ZSTD, dev(# lo_ordertotalprice INTEGER NOT NULL ENCODE ZSTD, dev(# lo_discount INTEGER NOT NULL ENCODE ZSTD, dev(# lo_revenue INTEGER NOT NULL ENCODE ZSTD, dev(# lo_supplycost INTEGER NOT NULL ENCODE AZ64, dev(# lo_tax INTEGER NOT NULL ENCODE AZ64, dev(# lo_commitdate INTEGER NOT NULL ENCODE AZ64, dev(# lo_shipmode VARCHAR(10) NOT NULL ENCODE ZSTD dev(# ); dev(# dev(# copy sample.lineorder from 's3://awssampledbuswest2/ssbgz/lineorder' dev(# iam_role 'arn:aws:iam::XXXXXXXXXXXX:role/TestRole' dev(# gzip region 'us-west-2'; dev(# dev=# select count(*) from sample.lineorder; count ----------- 600037902 (1 row) dev=#
列圧縮エンコーディングの変更
ANALYZE COMPRESSION
コマンドを実行し、最適な列圧縮エンコーディング、その列圧縮エンコーディングに変更した場合の推定減少パーセントを確認します
dev=# analyze compression sample.lineorder; Table | Column | Encoding | Est_reduction_pct -----------+--------------------+----------+------------------- lineorder | lo_orderkey | delta32k | 21.48 lineorder | lo_linenumber | az64 | 0.00 lineorder | lo_custkey | az64 | 0.00 lineorder | lo_partkey | az64 | 0.00 lineorder | lo_suppkey | az64 | 16.38 lineorder | lo_orderdate | az64 | 0.00 lineorder | lo_orderpriority | bytedict | 60.65 lineorder | lo_shippriority | zstd | 0.00 lineorder | lo_quantity | az64 | 0.00 lineorder | lo_extendedprice | zstd | 0.00 lineorder | lo_ordertotalprice | zstd | 0.00 lineorder | lo_discount | az64 | 17.79 lineorder | lo_revenue | zstd | 0.00 lineorder | lo_supplycost | az64 | 0.00 lineorder | lo_tax | az64 | 0.00 lineorder | lo_commitdate | az64 | 0.00 lineorder | lo_shipmode | bytedict | 19.14 (17 rows) dev=#
テーブルデータのストレージ使用量(単位:MB)も確認しておきます
dev=# select name as tbl_name, cnt as size from dev-# ( dev(# select tbl, count(*) as cnt dev(# from stv_blocklist dev(# where tbl in ( dev(# select id dev(# from stv_tbl_perm) dev(# group by tbl dev(# ) block_list dev-# inner join stv_tbl_perm dev-# on block_list.tbl=stv_tbl_perm.id dev-# group by tbl, stv_tbl_perm.name, block_list.cnt dev-# order by cnt; tbl_name | size -----------------------------------+------ lineorder | 24816 (1 row) dev=#
推定減少パーセントが一番高いlo_orderpriority
カラムの列圧縮エンコーディングを変更してみます。
dev=# alter table sample.lineorder alter column lo_orderpriority encode bytedict; ALTER TABLE dev=# dev=# select "column", type, encoding from pg_table_def where tablename = 'lineorder' and "column" = 'lo_orderpriority'; column | type | encoding ------------------+-----------------------+---------- lo_orderpriority | character varying(15) | bytedict (1 row) dev=#
列圧縮エンコーディングを期待通り変更できました!
dev=# select name as tbl_name, cnt as size from dev-# ( dev(# select tbl, count(*) as cnt dev(# from stv_blocklist dev(# where tbl in ( dev(# select id dev(# from stv_tbl_perm) dev(# group by tbl dev(# ) block_list dev-# inner join stv_tbl_perm dev-# on block_list.tbl=stv_tbl_perm.id dev-# group by tbl, stv_tbl_perm.name, block_list.cnt dev-# order by cnt; tbl_name | size -----------------------------------+------ lineorder | 23862
テーブルデータのストレージ使用量(単位:MB)が減少していることも確認できました。
注意点
ALTER TABLEコマンドで列圧縮エンコーディングを変更する場合は、下記注意が必要です。
You can't alter a column to the same encoding as currently defined for the column.
既に対象カラムに設定されている列圧縮エンコーディングを指定するとエラーになります。
dev=# alter table sample.lineorder alter column lo_shippriority encode zstd; ERROR: ALTER COLUMN ENCODE does not support changing to same encode type: zstd dev=#
You can't alter the encoding for a column in a table with an interleaved sortkey.
interleaved sortkeyで指定されているカラムの列圧縮エンコーディングを変更しようとするとエラーになります。
dev=# alter table sample.test alter column cust_id encode zstd; ERROR: Unsupported ALTER TABLE ALTER COLUMN ENCODE on table with interleaved sortkey. dev=#
おわりに
下記ブログにてテーブルを再作成して列圧縮エンコーディングの変更をする方法を書いたのですが、今回試したALTER TABLEコマンドでの変更が楽だったので個人的には非常にありがたいアップデートでした!これからは気軽に列圧縮エンコーディングの変更ができそうですね!
どなたかの参考になれば幸いです。以上、DA(データアナリティクス)事業本部のナガマサでした。